import crypto from 'crypto';
import { promisify } from 'node:util';
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';

// 获取当前文件的路径
const __filename = fileURLToPath(import.meta.url);
// 获取当前文件的目录路径
const __dirname = path.dirname(__filename);
const KEY_PATH = path.resolve(__dirname, 'keys');

// 密钥对象
let regPublicKey = null;
let regPrivateKey = null;
let jwtPublicKey = null;
let jwtPrivateKey = null;

// 保存密钥到文件
const saveKeys = (keyName, publicKey, privateKey) => {
  if (!fs.existsSync(KEY_PATH)) fs.mkdirSync(KEY_PATH);
  fs.writeFileSync(path.join(KEY_PATH, `${keyName}-public.pem`), publicKey);
  fs.writeFileSync(path.join(KEY_PATH, `${keyName}-private.pem`), privateKey);
};

// 从文件读取密钥
const loadKeys = (keyName) => {
  const publicKey = fs.readFileSync(path.join(KEY_PATH, `${keyName}-public.pem`), 'utf8');
  const privateKey = fs.readFileSync(path.join(KEY_PATH, `${keyName}-private.pem`), 'utf8');
  return { publicKey, privateKey };
};

const generateKeyPair = promisify(crypto.generateKeyPair);

// 初始化注册密钥对
export const initRegKeys = async () => {
  if (fs.existsSync(path.join(KEY_PATH, 'reg-public.pem'))) {
    const keys = loadKeys('reg');
    regPublicKey = keys.publicKey;
    regPrivateKey = keys.privateKey;
    return keys;
  }

  const { publicKey: pub, privateKey: priv } = await generateKeyPair('rsa', {
    modulusLength: 2048,
    publicKeyEncoding: {
      type: 'spki',
      format: 'pem'
    },
    privateKeyEncoding: {
      type: 'pkcs8',
      format: 'pem',
      cipher: 'aes-256-cbc',
      passphrase: process.env.RSA_PASSPHRASE
    }
  });

  regPublicKey = pub;
  regPrivateKey = priv;
  saveKeys('reg', regPublicKey, regPrivateKey);
  return { publicKey: regPublicKey, privateKey: regPrivateKey };
};

// 初始化 JWT 密钥对
export const initJWTKeys = async () => {
  if (fs.existsSync(path.join(KEY_PATH, 'jwt-public.pem'))) {
    const keys = loadKeys('jwt');
    jwtPublicKey = keys.publicKey;
    jwtPrivateKey = keys.privateKey;
    return keys;
  }

  const { publicKey: pub, privateKey: priv } = await generateKeyPair('rsa', {
    modulusLength: 2048,
    publicKeyEncoding: {
      type: 'spki',
      format: 'pem'
    },
    privateKeyEncoding: {
      type: 'pkcs8',
      format: 'pem',
      cipher: 'aes-256-cbc',
      passphrase: process.env.JWT_PASSPHRASE
    }
  });

  jwtPublicKey = pub;
  jwtPrivateKey = priv;
  saveKeys('jwt', jwtPublicKey, jwtPrivateKey);
  return { publicKey: jwtPublicKey, privateKey: jwtPrivateKey };
};

// 获取注册公钥
export const getRegPublicKey = async () => {
  if (!regPublicKey) throw new Error('注册公钥未初始化');
  return regPublicKey;
};

// 获取注册私钥
export const getRegPrivateKey = async () => {
  if (!regPrivateKey) throw new Error('注册私钥未初始化');
  return regPrivateKey;
};

// 获取 JWT 公钥
export const getJWTPublicKey = async () => {
  if (!jwtPublicKey) throw new Error('JWT 公钥未初始化');
  return jwtPublicKey;
};

// 获取 JWT 私钥
export const getJWTPrivateKey = async () => {
  if (!jwtPrivateKey) throw new Error('JWT 私钥未初始化');
  return jwtPrivateKey;
};

/**
 * 使用私钥解密数据
 * @param {string} encryptedData - 加密后的数据（Base64 编码字符串）
 * @returns {string} 解密后的原始数据
 */
export const decryptData = async (encryptedData) => {
  try {
    // 1. 获取注册私钥
    const privateKey = await getRegPrivateKey();

    // 2. 解码 Base64 加密数据
    const buffer = Buffer.from(encryptedData, 'base64');

    // 解密数据
    const decryptedStr = crypto.privateDecrypt(
      {
        key: privateKey,
        passphrase: process.env.RSA_PASSPHRASE,
        padding: crypto.constants.RSA_PKCS1_PADDING, // 改用OAEP填充
        oaepHash: 'sha256' // 必须指定哈希算法
      },
      buffer
    ).toString('utf8');

    // 解析为对象
    const data = JSON.parse(decryptedStr);
    console.log('解密后的数据:', data);
    return data;
  } catch (err) {
    console.error('解密失败:', err);
    throw err;
  }
};